<html>
    <head>
        <title>freemarker-tags 0.6.1 - Reference Documentation</title>
        <link rel="stylesheet" href="../css/main.css" type="text/css" media="screen" title="Style" charset="utf-8"/>
        <link rel="stylesheet" href="../css/pdf.css" type="text/css" media="print" title="PDF" charset="utf-8" />
    </head>
    <body class="body">
        <div id="header">
            <div class="images"><br/><br/>
                <a href="http://grails.org" target="_blank"><img alt="The Grails Framework" src="../img/grails.png" border="0"/></a>
                <span style="right:30px; top:20px; position:absolute;">
                    <a href="../index.html" target="_top">Frames</a> | <a href="index.html" target="_top">No Frames</a><br/><br/>
                    <a href="http://springsource.com" target="_blank"><img alt="SpringSource - A Division of VMware" src="../img/springsource-logo.png" border="0"/></a>
                </span>
            </div>
            <div class="message">freemarker-tags</div>
            <h1>freemarker-tags - Reference Documentation</h1>
            <p><strong>Authors:</strong> Daniel Henrique Alves Lima (text revised by Gislaine Fonseca Ribeiro and others)</p>
            <p><strong>Version:</strong> 0.6.1</p>
            <em></em>
        </div>

        <div id="toc">
            <h2>Table of Contents</h2>
            <div class="tocItem" style="margin-left:0px"><a href="#1. Introduction">1. Introduction</a></div><div class="tocItem" style="margin-left:10px"><a href="#1.1 Quick Start">1.1 Quick Start</a></div><div class="tocItem" style="margin-left:0px"><a href="#2. Usage">2. Usage</a></div><div class="tocItem" style="margin-left:10px"><a href="#2.1. Syntax tips (GSP vs. FTL)">2.1. Syntax tips (GSP vs. FTL)</a></div><div class="tocItem" style="margin-left:20px"><a href="#2.1.1. Maps vs. Hashes">2.1.1. Maps vs. Hashes</a></div><div class="tocItem" style="margin-left:20px"><a href="#2.1.2. Tags vs. Tags">2.1.2. Tags vs. Tags</a></div><div class="tocItem" style="margin-left:20px"><a href="#2.1.3. Tags as method calls vs. Method calls">2.1.3. Tags as method calls vs. Method calls</a></div><div class="tocItem" style="margin-left:0px"><a href="#3. Miscellaneous">3. Miscellaneous</a></div><div class="tocItem" style="margin-left:10px"><a href="#3.1. Configuration">3.1. Configuration</a></div><div class="tocItem" style="margin-left:10px"><a href="#3.2. Logging">3.2. Logging</a></div><div class="tocItem" style="margin-left:10px"><a href="#3.4. Reserved words">3.4. Reserved words</a></div><div class="tocItem" style="margin-left:0px"><a href="#4. Version History">4. Version History</a></div>
        </div>
        <div id="content">
            <h1><a name="1. Introduction">1. Introduction</a></h1>With this plugin you can use the <a href="http://www.grails.org/Dynamic+Tag+Libraries" target="blank">Grails Dynamic Tag Libraries</a> in <a href="http://freemarker.sourceforge.net/" target="blank">FreeMarker</a> templates. No JSP tag libraries are involved at all, the plugin connects FreeMarker to Grails TagLibs system as directly as possible.<p class="paragraph"/><h2><a name="1.1 Quick Start">1.1 Quick Start</a></h2>Create your Grails application<p class="paragraph"/><div class="code"><pre>grails create&#45;app test&#45;freemaker&#45;prj
cd test&#45;freemaker&#45;prj</pre></div><p class="paragraph"/>
Install the plugin<p class="paragraph"/><div class="code"><pre>grails install&#45;plugin freemarker&#45;tags</pre></div><p class="paragraph"/>
Create a domain class<p class="paragraph"/><div class="code"><pre>grails create&#45;domain&#45;class MyUser</pre></div><p class="paragraph"/>
Add some fields and validations to your grails-app/domain/test/freemaker/prj/MyUser.groovy<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">static</span> constraints = &#123;
    username(unique: <span class="java&#45;keyword">true</span>, blank: <span class="java&#45;keyword">false</span>)
    password(blank: <span class="java&#45;keyword">false</span>)
  &#125;<p class="paragraph"/>  <span class="java&#45;object">String</span> username
  <span class="java&#45;object">String</span> password</pre></div><p class="paragraph"/>
Generate a controller<p class="paragraph"/><div class="code"><pre>grails generate&#45;controller test.freemaker.prj.MyUser</pre></div><p class="paragraph"/>
Add new actions to your grails-app/controllers/test/freemaker/prj/MyUserController.groovy<p class="paragraph"/><div class="code"><pre>def login = &#123;
      def myUserInstance = <span class="java&#45;keyword">new</span> MyUser()
      render(view: <span class="java&#45;quote">"login"</span>, model: &#91;myUserInstance: myUserInstance&#93;)
    &#125;<p class="paragraph"/>    def doLogin = &#123;
      def myUserInstance = <span class="java&#45;keyword">new</span> MyUser(params)<p class="paragraph"/>      <span class="java&#45;object">boolean</span> ok = myUserInstance.validate(&#91;'password'&#93;) 
      <span class="java&#45;keyword">if</span> (ok) &#123;
	<span class="java&#45;keyword">if</span> (!myUserInstance.username || !myUserInstance.password || !myUserInstance.password.equals(<span class="java&#45;quote">"pass"</span>)) &#123;
	  flash.message = <span class="java&#45;quote">"$&#123;message(code: 'Invalid password or username', args: &#91;&#93;)&#125;"</span>
	  ok = <span class="java&#45;keyword">false</span>
	&#125;
      &#125;<p class="paragraph"/>      <span class="java&#45;keyword">if</span> (ok) &#123;
	redirect(action: <span class="java&#45;quote">"index"</span>)
      &#125; <span class="java&#45;keyword">else</span> &#123;
	myUserInstance.password = <span class="java&#45;keyword">null</span>
	render(view: <span class="java&#45;quote">"login"</span>, model: &#91;myUserInstance: myUserInstance&#93;)
      &#125;
    &#125;</pre></div><p class="paragraph"/>
Create your grails-app/views/myUser/login.ftl<p class="paragraph"/><div class="code"><pre>&#60;&#35;ftl /&#62;<p class="paragraph"/>&#60;html&#62;
  &#60;head&#62;
    &#60;meta http&#45;equiv=<span class="java&#45;quote">"Content&#45;Type"</span> content=<span class="java&#45;quote">"text/html; charset=UTF&#45;8"</span> /&#62;
    &#60;meta name=<span class="java&#45;quote">"layout"</span> content=<span class="java&#45;quote">"main"</span> /&#62;
  &#60;/head&#62;
  &#60;body&#62;
    &#60;div class=<span class="java&#45;quote">"body"</span>&#62;
      &#60;&#35;<span class="java&#45;keyword">if</span> flash.message?exists&#62;&#60;div class=<span class="java&#45;quote">"message"</span>&#62;$&#123;flash.message&#125;&#60;/div&#62;&#60;/&#35;<span class="java&#45;keyword">if</span>&#62;
      &#60;@g.hasErrors bean=myUserInstance&#62;
        &#60;div class=<span class="java&#45;quote">"errors"</span>&#62;
          &#60;@g.renderErrors bean=myUserInstance _as=<span class="java&#45;quote">"list"</span> /&#62;
        &#60;/div&#62;
      &#60;/@g.hasErrors&#62; 
      &#60;@g.form action=<span class="java&#45;quote">"doLogin"</span> method=<span class="java&#45;quote">"post"</span>&#62;
	&#60;div class=<span class="java&#45;quote">"dialog"</span>&#62;
	  &#60;table&#62;
            &#60;tr class=<span class="java&#45;quote">"prop"</span>&#62;
              &#60;td valign=<span class="java&#45;quote">"top"</span> class=<span class="java&#45;quote">"name"</span>&#62;
		&#60;label <span class="java&#45;keyword">for</span>=<span class="java&#45;quote">"username"</span>&#62;&#60;@g.message code=<span class="java&#45;quote">"myUser.username.label"</span> <span class="java&#45;keyword">default</span>=<span class="java&#45;quote">"Username"</span> /&#62;&#60;/label&#62;
              &#60;/td&#62;
              &#60;td valign=<span class="java&#45;quote">"top"</span> class=<span class="java&#45;quote">"value $&#123;g._hasErrors(&#123;'bean': myUserInstance, 'field': 'username'&#125;, 'errors')&#125;"</span>&#62;
		&#60;@g.textField name=<span class="java&#45;quote">"username"</span> value=myUserInstance.username /&#62;
            &#60;/td&#62;
            &#60;/tr&#62;	  
            &#60;tr class=<span class="java&#45;quote">"prop"</span>&#62;
              &#60;td valign=<span class="java&#45;quote">"top"</span> class=<span class="java&#45;quote">"name"</span>&#62;
		&#60;label <span class="java&#45;keyword">for</span>=<span class="java&#45;quote">"password"</span>&#62;&#60;@g.message code=<span class="java&#45;quote">"myUser.password.label"</span> <span class="java&#45;keyword">default</span>=<span class="java&#45;quote">"Password"</span> /&#62;&#60;/label&#62;
              &#60;/td&#62;
              &#60;td valign=<span class="java&#45;quote">"top"</span> class=<span class="java&#45;quote">"value $&#123;g._hasErrors(&#123;'bean': myUserInstance, 'field': 'password'&#125;, 'errors')&#125;"</span>&#62;
		&#60;@g.passwordField name=<span class="java&#45;quote">"password"</span> value=myUserInstance.password /&#62;
              &#60;/td&#62;
            &#60;/tr&#62;
	  &#60;/table&#62;
	&#60;/div&#62;
        &#60;div class=<span class="java&#45;quote">"buttons"</span>&#62;
          &#60;span class=<span class="java&#45;quote">"button"</span>&#62;&#60;@g.submitButton name=<span class="java&#45;quote">"submit"</span> value=<span class="java&#45;quote">"$&#123;g._message(&#123;'code': '<span class="java&#45;keyword">default</span>.button.login.label', '<span class="java&#45;keyword">default</span>': 'Login'&#125;)&#125;"</span> /&#62;&#60;/span&#62;
        &#60;/div&#62;
      &#60;/@g.form&#62;
    &#60;/div&#62;
  &#60;/body&#62;
&#60;/html&#62;</pre></div><p class="paragraph"/>
Use your browser to navigate to http://localhost:8080/test-freemaker-prj/myUser/login<p class="paragraph"/>Done!<p class="paragraph"/><blockquote class="note">
In FreeMarker templates, you can use &#60; &#62; or &#91; ]. For more information, please consult <a href="http://freemarker.sourceforge.net/docs/app_faq.html#faq_alternative_syntax" target="blank">Freemarker FAQ</a> about alternative syntax.
</blockquote><p class="paragraph"/><blockquote class="warning">
Be aware that FreeMarker syntax differs from GSP syntax (they are different beasts).
</blockquote><h1><a name="2. Usage">2. Usage</a></h1>The plugin will try to expose all the TagLib artefacts, registered at grailsApplication.tagLibsClasses, as user-defined directives and functions (for implementation details, please refer to <a href="http://freemarker.sourceforge.net/docs/app_faq.html#faq_implement_function_or_macro_in_java" target="blank">FreeMarker FAQ</a> ). These directives and functions will be defined at runtime and they will be auto-imported, using the same namespace of the source taglibs, in any FreeMarker template created further.
Some of these behaviors are "controllable" through configuration.<p class="paragraph"/>
<h2><a name="2.1. Syntax tips (GSP vs. FTL)">2.1. Syntax tips (GSP vs. FTL)</a></h2>The following items contain useful information about some of the differences between Grails Server Pages (.gsp) and FreeMarker Templates (.ftl). Please note this is not intended to be a complete list, it's just a starting point for begginers.<p class="paragraph"/><h2><a name="2.1.1. Maps vs. Hashes">2.1.1. Maps vs. Hashes</a></h2>.gsp<p class="paragraph"/><div class="code"><pre>&#91;key1: 'abc', key2: 2&#93;</pre></div><p class="paragraph"/>
.ftl<p class="paragraph"/><div class="code"><pre>&#123;'key1': 'abc', 'key2': 2&#125;</pre></div><p class="paragraph"/><h2><a name="2.1.2. Tags vs. Tags">2.1.2. Tags vs. Tags</a></h2>.gsp<p class="paragraph"/><div class="code"><pre>&#60;g:includeJs script=<span class="java&#45;quote">"myscript"</span> /&#62;</pre></div><p class="paragraph"/>
.ftl<p class="paragraph"/><div class="code"><pre>&#60;@g.includeJs script=<span class="java&#45;quote">"myscript"</span> /&#62;</pre></div><p class="paragraph"/>or<p class="paragraph"/><div class="code"><pre>&#91;@g.includeJs script=<span class="java&#45;quote">"myscript"</span> /&#93;</pre></div><p class="paragraph"/>
Parameter values are (arbitrary complex) expressions that are not quoted. So assuming you want to pass an integer to foo, &#60;&#64;foo bar=1 /&#62; is good, but &#60;&#64;foo bar="1" /&#62; is wrong as it passes in the value as a string (because "1" is a string literal, just like in Groovy). For the same reason, &#60;&#64;foo bar=x+1 /&#62; is good, but &#60;&#64;foo bar="${x+1}" /&#62; does something else.<p class="paragraph"/><h2><a name="2.1.3. Tags as method calls vs. Method calls">2.1.3. Tags as method calls vs. Method calls</a></h2>.gsp<p class="paragraph"/><div class="code"><pre>&#60;span id=<span class="java&#45;quote">"title"</span> class=<span class="java&#45;quote">"label $&#123;hasErrors(bean:book,field:'title','errors')&#125;"</span>&#62;Title&#60;/span&#62;</pre></div><p class="paragraph"/>
.ftl<p class="paragraph"/><div class="code"><pre>&#60;span id=<span class="java&#45;quote">"title"</span> class=<span class="java&#45;quote">"label $&#123;g.hasErrors(&#123;'bean':book,'field':'title'&#125;,'errors')&#125;"</span>&#62;Title&#60;/span&#62;</pre></div><p class="paragraph"/>
<blockquote class="note">
The plugin will define functions using the same namespace of the corresponding directives.
All functions will receive two parameters, at most: a hash and an evaluated string. 
</blockquote><p class="paragraph"/>
<blockquote class="warning">
To enable "_" prefixing of function names, please refer to <a href="../guide/single.html#3.1. Configuration" class="guide">Configuration</a>.
</blockquote>
<h1><a name="3. Miscellaneous">3. Miscellaneous</a></h1>
<h2><a name="3.1. Configuration">3.1. Configuration</a></h2><div class="code"><pre>grails.plugins.freemarkertags = &#91;
  autoImport: <span class="java&#45;keyword">true</span>,                   /&#42; To enable or to disable auto&#45;<span class="java&#45;keyword">import</span> feature. When disabled the generated libraries can be imported using FreeMarker <span class="java&#45;keyword">default</span> mechanism. &#42;/
  defineLegacyFunctions: <span class="java&#45;keyword">false</span>,       /&#42; To enable or to disable <span class="java&#45;quote">"legacy"</span> (name starting with '_') function declaration/definition feature. &#42;/
  asSharedVariables: <span class="java&#45;keyword">false</span>,           /&#42; EXPERIMENTAL: To expose directives and functions as shared variables, avoiding extra object creation at every template rendering. &#42;/<p class="paragraph"/>  viewResolver: &#91;
     legacyHideExceptions: <span class="java&#45;keyword">false</span>     /&#42; To enable or to disable the <span class="java&#45;quote">"feature"</span> of hiding exceptions thrown by FreeMarkerViewResolver. It will also affect how those exceptions will be logged. &#42;/
  &#93;
&#93;</pre></div><p class="paragraph"/>
<blockquote class="warning">
When using asSharedVariables = true, be aware that some templates can mistakenly/inadvertently "shadow" shared variables definitions.<p class="paragraph"/>Because this feature is still experimental there is no garantee that tags will work in a "Thread safe" way.
</blockquote>
<h2><a name="3.2. Logging">3.2. Logging</a></h2>You can enable plugin activity logging using the namespace 'org.codehaus.groovy.grails.plugins.freemarker'.<p class="paragraph"/>For more information about Grails logging, please consult: <a href="http://grails.org/doc/latest/guide/3.%20Configuration.html#3.1.2%20Logging" target="blank">Grails Logging</a>
<h2><a name="3.4. Reserved words">3.4. Reserved words</a></h2>FreeMarker reserved words present in Grails Core TagLibs that can cause errors to FreeMarker's parser, will be preceded by '_' (underscore).<p class="paragraph"/>.gsp<p class="paragraph"/><div class="code"><pre>&#60;g:renderErrors bean=<span class="java&#45;quote">"$&#123;myUserInstance&#125;"</span> as=<span class="java&#45;quote">"list"</span> /&#62;</pre></div><p class="paragraph"/>
.ftl<p class="paragraph"/><div class="code"><pre>&#60;@g.renderErrors bean=myUserInstance _as=<span class="java&#45;quote">"list"</span> /&#62;</pre></div><p class="paragraph"/>or<p class="paragraph"/><div class="code"><pre>&#91;@g.renderErrors bean=myUserInstance _as=<span class="java&#45;quote">"list"</span> /&#93;</pre></div><p class="paragraph"/><h1><a name="4. Version History">4. Version History</a></h1><ul class="star">
<li>0.5.8</li>
<ul class="star">
<li>Fixed GroovyPageOutputStack usage</li>
<li>Functions names are no longer prefixed by "_"</li>
<li>Added EXPERIMENTAL support to expose functions and directives as shared variables</li>
</ul>
<li>0.5.9</li>
<ul class="star">
<li>Required version of Grails was reduced from 1.3.3 to 1.2.5</li>
<li>Exceptions thrown during the execution of FreeMarkerViewResolver.loadView() are no longer hidden</li>
</ul>
<li>0.6.0</li>
<ul class="star">
<li>Added specialized subclass of FreeMarkerConfigurer, increasing the range of use cases for the plugin</li>
</ul>
<li>0.6.1</li>
<ul class="star">
<li>Modified atts subclass (LinkedHashMap changed to GroovyPageAttributes)</li>
<li>Fixed calls to closures with an additional parameter (body)</li>
</ul></ul><p class="paragraph"/>
        </div>
        <div id="footer">
             
        </div>
    </body>
</html>
